package leetcode.easy;

import java.util.*;

/**
 * @author 马迪迪
 * @description: TODO
 * @data 2025年04月28日22时57分
 * 给你一个由 正 整数组成的数组 nums。
 * 如果数组中的某个子数组满足下述条件，则称之为 完全子数组；
 * 子数组中不同元素的数目等于整个数组不同元素的数目
 * 返回数组中的一个链接非空序列
 * <p>
 * 示例1：
 * 输入：nums =[1,3,1,2,2]
 * 输出：4
 * 解释：完全子数组有：[1,3,1,2]、[1,3,1,2,2]、[3,1,2]和[3,1,2,2]
 * <p>
 * 示例2：
 * 输入：nums = [5,5,5,5]
 * 输出：10
 * 解释：数组仅由整数 5 组成，所以任意子数组都能满足子数组的条件。子数组的总数为 10
 */
public class 统计完全子数组的数目 {

    public static void main(String[] args) {
//        int[] nums = {1, 3, 1, 2, 2};
//        int[] nums = {5, 5, 5, 5};
        int[] nums = {1188, 117, 1021, 770, 1188, 1021, 1188, 373, 132, 1717, 1253, 24, 1679, 749, 1188, 1188, 770, 1169, 890, 1725, 1477, 749, 691, 698, 1021, 883, 1956, 543, 596, 249, 249, 1309, 1348, 1586, 225, 1188, 169, 698, 440, 719, 1125, 749, 1166, 1021, 1762, 440, 132, 1731, 770, 1911, 1904, 404, 1188, 66, 404, 1263, 1903, 1911, 1164, 685, 698, 740, 1105, 491, 314, 1131, 1751, 1105, 362, 1612, 1717, 465, 925, 105, 1319, 1881, 1130, 465, 1166, 1933, 1549, 313, 688, 142, 476, 305, 883, 1872, 805, 232, 401, 448, 1166, 1062, 1368, 1814, 1188, 1937, 1911, 1922, 1368, 1267, 1105, 786, 1438, 93, 1018, 1584, 1430, 132, 1967, 710, 1078, 404, 1624, 1943, 1130, 629, 317, 1797, 1095, 1164, 69, 660, 1688, 1169, 1718, 225, 20, 1672, 1269, 523, 404, 78, 666, 346, 1346, 1157, 1133, 198, 1131, 1105, 1559, 1435, 35, 1036, 1088, 1797, 765, 1368, 1672, 610, 235, 291, 1540, 1589, 187, 317, 1632, 1036, 1709, 787, 961, 1688, 1213, 583, 1263, 405, 1720, 440, 202, 629, 1269, 1284, 1632, 284, 1270, 635, 1749, 107, 1586, 638, 1926, 826, 46, 950, 1602, 536, 1352, 154, 401, 107, 1304, 779, 107, 1105, 950, 1716, 536, 563, 723, 1672, 178, 1474, 1010, 1669, 481, 1697, 778, 889, 20, 235, 1015, 665, 678, 1126, 685, 977, 1429, 287, 11, 489, 981, 1008, 1856, 1188, 298, 1188, 1332, 225, 1498, 1908, 1188, 1134, 787, 139, 749, 1293, 78, 1162, 687, 178, 668, 1019, 749, 813, 1062, 1965, 1212, 1879, 545, 167, 293, 1904, 465, 21, 1031, 813, 573, 1049, 842, 362, 783, 1253, 20, 464, 1774, 182, 1718, 113, 187, 778, 437, 1396, 840, 404, 848, 18, 1164, 346, 1451, 1457, 1150, 1514, 1652, 336, 1716, 125, 1933, 717, 178, 1852, 770, 64, 1168, 374, 225, 94, 1075, 1238, 1007, 188, 1692, 423, 1695, 863, 1864, 1650, 1253, 889, 125, 379, 1379, 1105, 1079, 563, 1413, 942, 1717, 1740, 1361, 214, 1863, 1190, 203, 1368, 1679, 753, 1304, 1998, 961, 1188, 1224, 760, 317, 314, 1965, 1694, 659, 576, 285, 1672, 691, 73, 1976, 1018, 1934, 1003, 1577, 651, 1346, 1669, 206, 154, 1192, 169, 237, 1762, 1914, 198, 483, 808, 156, 1697, 1125, 1309, 1304, 929, 1188, 586, 1945, 747, 1903, 1672, 1224, 812, 1238, 614, 247, 901, 1384, 1881, 24, 1688, 277, 1253, 1595, 374, 893, 351, 47, 35, 238, 852, 963, 691, 101, 1586, 611, 1577, 936, 1024, 698, 379, 543, 597, 1, 1125, 1615, 208, 1014, 186, 495, 1354, 441, 740, 27, 1933, 1933, 1212, 1188, 1413, 185, 613, 404, 1663, 1077, 852, 691, 1171, 620, 1815, 1393, 1150, 224, 1311, 1379, 1680, 1269, 404, 293, 647, 536, 565, 647, 1379, 1995, 978, 105, 1934, 329, 1263};
        int val0 = countCompleteSubArrays0(nums);
        int val1 = countCompleteSubArrays1(nums);
        System.out.println(val0);
        System.out.println(val1);
    }

    /**
     * 滑动窗口方式
     * @param nums
     * @return
     */
    public static int countCompleteSubArrays0(int[] nums) {
        Set<Integer> set = new HashSet<>();
        for (int i = 0; i < nums.length; i++) {
            set.add(nums[i]);
        }
        int k = set.size();
        Map<Integer, Integer> cnt = new HashMap<>();
        int ans = 0;
        int left = 0;
        for (int num : nums) {
            cnt.merge(num, 1, Integer::sum);
            while (cnt.size() == k) {
                int out = nums[left];
                if (cnt.merge(out, -1, Integer::sum) == 0) {
                    cnt.remove(out);
                }
                left++;
            }
            ans += left;
        }
        return ans;
    }

    /**
     * 使用 暴力枚举方式便利和判断处理
     *
     * @param nums
     * @return
     */
    public static int countCompleteSubArrays1(int[] nums) {
        int count = 0;
        int n = nums.length;
        Set<Integer> numSet = new HashSet<>();
        for (int i = 0; i < n; i++) {
            numSet.add(nums[i]);
        }
        int numSetSize = numSet.size();

        for (int i = 0; i <= n - numSetSize; i++) {
            for (int j = i; j < n; j++) {
                List<Integer> arr = new ArrayList<>();
                for (int k = i; k <= j; k++) {
                    arr.add(nums[k]);
                }
                if (arr.size() >= numSetSize) {
                    // 根据逻辑判断
                    long arrCount = numSet.stream().filter(item -> !arr.contains(item)).count();
                    if (arrCount == 0) count++;
                }
            }
        }

        return count;
    }

}
